import 'dart:convert';
import 'dart:typed_data';

import 'package:event_bus/event_bus.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
import 'package:wk_robot2/app/blt/RobotCommands.dart';
import 'package:wk_robot2/app/const/AppConst.dart';
import 'package:wk_robot2/app/event/MsgContentEvent.dart';
import 'package:wk_robot2/app/models/Devices.dart';
import 'package:wk_robot2/app/storage/StorageManager.dart';
import 'package:crypto/crypto.dart';

import '../event/DataCallBack.dart';
import '../event/MsgContentEvent.dart';
import '../event/WkEventListener.dart';
import '../modules/PermissionSetting/controllers/permission_setting_controller.dart';
import '../routes/app_pages.dart';
import '../widget/CommonWidgets.dart';
import '../widget/tips.dart';
import 'NetWorkUtil.dart';
import 'PermissionUtil.dart';

class CommonUtil {
  static bool isEmail(String input) {
    if (input.isEmpty) return false;
    return RegExp("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$").hasMatch(input);
  }

  static bool isChinaPhoneLegal (String str) {
    return new RegExp('^((13[0-9])|(15[^4])|(166)|(17[0-8])|(18[0-9])|(19[8-9])|(147,145))\\d{8}\$').hasMatch(str);
  }


  //有可能为空.
  static String getBltDeviceSN() { //检查设备是否绑定和绑定场景需要,重新连接设备的时候也需要.
    if(StorageManager.getStorage().hasData(AppConst.BLT_DEVICE_SN_CURRENTLY)) {
      return StorageManager.getStorage().read(AppConst.BLT_DEVICE_SN_CURRENTLY);
    } else {
      return '';
    }
  }

  static String getBltDeviceTmpSN() { //检查设备是否绑定和绑定场景需要,重新连接设备的时候也需要.
    if(StorageManager.getStorage().hasData(AppConst.BLT_DEVICE_SN_CURRENTLY_TMP)) {
      return StorageManager.getStorage().read(AppConst.BLT_DEVICE_SN_CURRENTLY_TMP);
    } else {
      return '';
    }
  }


  static String getDeviceId() {
    if (StorageManager.getStorage().hasData(AppConst.storage_key_device_id)) {
      return StorageManager.getStorage().read(AppConst.storage_key_device_id);

    } else {
      String uuid = Uuid().v4();
      StorageManager.getStorage().write(AppConst.storage_key_device_id, uuid);
      return uuid;

    }
  }

  static int getLoginUserId() {
    if (StorageManager.getStorage().hasData(AppConst.storage_current_login_user)) {
      return StorageManager.getStorage().read(AppConst.storage_current_login_user)['userId'];

    } else {
      return 0;
    }
  }

  static Map getLoginUser() {
    if (StorageManager.getStorage().hasData(AppConst.storage_current_login_user)) {
      return StorageManager.getStorage().read(AppConst.storage_current_login_user);

    } else {
      return {};
    }
  }


  static String calculateMD5(String input) {
    // 将字符串转换为 Uint8List
    var  inputBytes = utf8.encode(input);

    // 计算 MD5 哈希值
    Digest digest = md5.convert(inputBytes);
    //md5.
    return digest.toString();
  }


  static Uint8List intToByteArray(int value, int byteSize) {
    // 创建一个足够大的 Uint8List 来存储字节
    Uint8List byteArray = Uint8List(byteSize);

    // 将 int 分解为字节并存储到 Uint8List 中
    for (int i = 0; i < byteSize; i++) {
      // 通过位移和位与操作获取每个字节
      byteArray[byteSize - 1 - i] = (value >> (i * 8)) & 0xFF;
    }

    return byteArray;
  }

  static int bytesToInt(Uint8List bytes) {
    // 注意：这里假设字节顺序是小端序（least significant byte first），如果不是，请调整
    int result = 0;
    for (int i = 0; i < bytes.length; i++) {
      // 将每个字节左移适当的位数，并将其添加到结果中
      result = (result << 8) | bytes[i];
    }
    return result;
  }

  static String uint8ListToHex(Uint8List uint8List) {
    String hexString = '';
    for (int byte in uint8List) {
      // 将每个字节转换为两位的十六进制字符串
      String hex = byte.toRadixString(16).padLeft(2, '0');
      hexString = hexString + hex;
    }
    return hexString.toString();
  }




  static Uint8List hexStringToBytes(String hex) {
    // 确保十六进制字符串的长度是偶数，因为每两个十六进制字符表示一个字节
    if (hex.length % 2 != 0) {
      throw ArgumentError('Invalid hex string length.');
    }

    final result = Uint8List(hex.length ~/ 2);
    for (int i = 0; i < hex.length; i += 2) {
      final byte = int.parse(hex.substring(i, i + 2), radix:16);
      result[i ~/ 2] = byte;
    }
    return result;
  }


  static Uint8List listToInt8List(List<int> inputList) {
    // 检查输入列表中的每个元素是否在有效范围内（0-255）
    for (int value in inputList) {
      if (value < 0 || value > 255) {
        throw ArgumentError('List contains values outside the valid range for Uint8List (0-255).');
      }
    }

    // 创建一个 Uint8List 并使用 inputList 中的值初始化它
    Uint8List uint8List = Uint8List.fromList(inputList);

    return uint8List;
  }


  //保存当前连接设备.
  static void saveOrUpdateCurrentConnectionDevices(Device data) {
    Device connectedDevice = Device();
    connectedDevice.robotUserId = data.robotUserId;
    connectedDevice.masterUserName = data.masterUserName;
    connectedDevice.masterUserId = data.masterUserId;
    StorageManager.getStorage().write(AppConst.CURRENT_CONNECTIONING_DEVICE, connectedDevice);
  }

  //获取当前连接设备.
  static Device? getCurrentConnectionDevices() {
    if(StorageManager.getStorage().hasData(AppConst.CURRENT_CONNECTIONING_DEVICE)) {
      return StorageManager.getStorage().read<Device>(AppConst.CURRENT_CONNECTIONING_DEVICE);
    } else {
      return null;
    }

  }

  static void refreshMyRobotList(List robots) {
    if (robots.length > 0) {
      if(StorageManager.getStorage().hasData(AppConst.MY_ROBOTS_LIST)) {
        List<Device> devicesFromLocal = getMyRobotLists();
        List<Device> newDevicesFromLocal = [];
        // 检查集合数目是否一致,过滤出已经未删除的Item.
        for (int i = 0; i < devicesFromLocal.length; i++) {
          Device localDevice  = devicesFromLocal[i];
          for (int j = 0; j < robots.length; j++) {
            if(robots[j]['robotUserId'] == localDevice.robotUserId) {
              newDevicesFromLocal.add(localDevice);
              break;
            }
          }

        }

        List<Device> newRobotLists = [];
        robots.forEach((newRobot) {
          Device newRobotItem = Device.fromJson(newRobot);

          newDevicesFromLocal.forEach((deviceItem) {
            if (newRobotItem.robotUserId == deviceItem.robotUserId) {
              updateDevices(newRobotItem, deviceItem.toJson());
            }
          });

          newRobotLists.add(newRobotItem);
        });

        StorageManager.getStorage().write(AppConst.MY_ROBOTS_LIST,json.encode(newRobotLists));
        //发送广播通知各个兴趣方.
        eventBus.fire(ProductContentEvent(ROBOT_LIST_HAVE_CHANGED));


      } else {
        List<Device> robotDevices = [];
        robots.forEach((robot) {
          Device devices = Device.fromJson(robot);
          robotDevices.add(devices);

        });

        StorageManager.getStorage().write(AppConst.MY_ROBOTS_LIST,json.encode(robotDevices));
        //发送广播通知各个兴趣方.
        eventBus.fire(ProductContentEvent(ROBOT_LIST_HAVE_CHANGED));
      }




    }


  }


  static List<Device> getMyRobotLists() {
    if (StorageManager.getStorage().hasData(AppConst.MY_ROBOTS_LIST)) {
      List<Device> robotDevices = [];
      List myrobots = json.decode(StorageManager.getStorage().read(AppConst.MY_ROBOTS_LIST));
      myrobots.forEach((robot) {
        robotDevices.add(Device.fromJson(robot));
      });

      return robotDevices;
    } else {
      return [];
    }

  }


  static void updateMyRobotLists(String robotUserId,Map<String ,dynamic> params) {
    List<Device> devicesRobots = getMyRobotLists();
    for (int i=0; i < devicesRobots.length; i++) {
      Device persistanceDevice = devicesRobots[i];
      if (persistanceDevice.robotUserId == robotUserId) {
        updateDevices(persistanceDevice,params);
        break;
      }
    }

    StorageManager.getStorage().write(AppConst.MY_ROBOTS_LIST,json.encode(devicesRobots));
    //发送广播通知各个兴趣方.
    eventBus.fire(ProductContentEvent(ROBOT_LIST_HAVE_CHANGED));
  }


  static void freshRobotMQTTInfo(String robotUserId,
      int powerValue,int levelStatus,bool isWifiOpen,int wifiSingle, bool isWifiConnected,
      String version,String cloundVersion) {
    updateMyRobotLists(
        robotUserId, {
      'powerValue': powerValue,
      'levelStatus': levelStatus,
      'isWifiOpen': isWifiOpen,
      'wifiSingle': wifiSingle,
      'isWifiConnected': isWifiConnected,
      'version':version,
      'cloundVersion': cloundVersion
    }
    );
  }


  static void updateDevices (Device persistanceDevice,Map<String ,dynamic> data) {
    if(data.containsKey('masterUserId'))
      persistanceDevice.masterUserId = data['masterUserId'];
    if(data.containsKey('masterUserName'))
      persistanceDevice.masterUserName = data['masterUserName'];
    if(data.containsKey('robotUserId'))
      persistanceDevice.robotUserId = data['robotUserId'];

    if(data.containsKey('powerValue'))
      persistanceDevice.powerValue = data['powerValue'];
    if(data.containsKey('levelStatus'))
      persistanceDevice.levelStatus = data['levelStatus'];
    if(data.containsKey('isWifiOpen'))
      persistanceDevice.isWifiOpen = data['isWifiOpen'];

    if(data.containsKey('wifiSingle'))
      persistanceDevice.wifiSingle = data['wifiSingle'];
    if(data.containsKey('isWifiConnected'))
      persistanceDevice.isWifiConnected = data['isWifiConnected'];
    if(data.containsKey('version'))
      persistanceDevice.version = data['version'];

    if(data.containsKey('cloundVersion'))
      persistanceDevice.cloundVersion = data['cloundVersion'];
    if(data.containsKey('isOnline'))
      persistanceDevice.isOnline = data['isOnline'];
    if(data.containsKey('selected'))
      persistanceDevice.selected = data['selected'];
    if(data.containsKey('wifiName'))
      persistanceDevice.wifiName = data['wifiName'];

  }


  //切换到当前机器人.
  static void switch2FavorRobot(String robotUserId) {
    List<Device> devicesRobots = getMyRobotLists();
    bool isHasSwitch = false;
    for (int i=0; i < devicesRobots.length; i++) {
      Device persistanceDevice = devicesRobots[i];
      if (persistanceDevice.robotUserId == robotUserId) {
        updateDevices(persistanceDevice,{
          'selected':true
        });
        isHasSwitch = true;

        StorageManager.getStorage().write(AppConst.BLT_DEVICE_SN_CURRENTLY,devicesRobots[0].robotUserId);

      } else {
        updateDevices(persistanceDevice,{
          'selected':false
        });

      }
    }

    if (!isHasSwitch && devicesRobots.isNotEmpty) {
      updateDevices(devicesRobots[0],{
        'selected':true
      });
      StorageManager.getStorage().write(AppConst.BLT_DEVICE_SN_CURRENTLY,devicesRobots[0].robotUserId);

    }

    StorageManager.getStorage().write(AppConst.MY_ROBOTS_LIST,json.encode(devicesRobots));
    //发送广播通知各个兴趣方.
    eventBus.fire(ProductContentEvent(ROBOT_LIST_HAVE_CHANGED));
  }


  static Device getCurrentSelectedRobot() {
    List<Device> devicesRobots = getMyRobotLists();
    for (int i=0; i < devicesRobots.length; i++) {
      Device persistanceDevice = devicesRobots[i];
      if (persistanceDevice.selected!) {
        return persistanceDevice;
      }
    }

    return Device();
  }


  static void clearAllRobots() {
    StorageManager.getStorage().write(AppConst.MY_ROBOTS_LIST,json.encode([]));
    StorageManager.getStorage().remove(AppConst.BLT_DEVICE_SN_CURRENTLY);
    //发送广播通知各个兴趣方.
    eventBus.fire(ProductContentEvent(ROBOT_LIST_HAVE_CHANGED));
  }







  static void bindDevices() async {

    List<Device> devices = CommonUtil.getMyRobotLists();
    if (devices.length >= 25) {
      Tips.showToast('最多只能绑定25台机器人');
      return;
    }


    // 绑定前检查,网络, 蓝牙和位置信息.
    bool isNetWork = await NetWorkUtil.checkNetWorkIsAvailable();
    if (!isNetWork) {
      Tips.showToast('手机网络不可用.');
      return;
    }

    bool bltAndLocation = await checkBlueteethAndLocationDisable();
    if (bltAndLocation) {
      Get.toNamed(Routes.PERMISSION_SETTING);
      return;
    }

    if(GetPlatform.isAndroid) {
      bool permissionAllGranted = await PermissionUtil.checkPermission();
      if (!permissionAllGranted) {
        Get.toNamed(Routes.PERMISSION_SETTING);
        return;
      }

      Get.toNamed(Routes.POWER_ONING);
    }else if(GetPlatform.isIOS) {

      // BluetoothPermissionChecker checker = BluetoothPermissionChecker();
      // bool isBluetoothReady = await checker.checkBluetoothStatus();
      // if (isBluetoothReady) {
      //   Get.toNamed(Routes.POWER_ONING);
      //   print("蓝牙已开启并且权限已授权！");
      // } else {
      //   Get.toNamed(Routes.PERMISSION_SETTING);
      // }

      var status = await Permission.bluetooth.status;
      if (status.isGranted) {
        Get.toNamed(Routes.POWER_ONING);
      }else {
        // 请求蓝牙权限
        // var result = await Permission.bluetooth.request();
        Get.toNamed(Routes.PERMISSION_SETTING);
      }

    }




    /* BltManager.instance.scanDevices(scanDeviceCallBack: DataCallBack(
        deviceCallBack: (param) {
          //设备连接成功.

        }
    ));*/



  }

  static void clearCache(DataCallBack dataCallBack) async {
    GetStorage().erase();
    dataCallBack.businessCallBack??(true);
  }

  static Future<bool> checkBlueteethAndLocationDisable () async {
    if (await PermissionUtil.locationDisabled()) {
      return true;
    }
    if (await PermissionUtil.bluetoothDisabled()) {
      return true;
    }
    return false;
  }



}